#include "helper_file.h"

#include "os.h"

namespace afcore {
namespace log {

CHelperFile::~CHelperFile() {
  Close();
}

void CHelperFile::Open(const RFileName& filename, bool truncate) {
  Close();
  filename_ = filename;
  auto* mode = truncate ? "wb" : "ab";

  for (int tries = 0; tries < open_tries_; ++tries) {
    CreateDir(DirName(filename));
    if (!Fileopen(&fd_, filename, mode)) {
      return;
    }
    SleepMillis(open_interval_);
  }

  ThrowCLogeException("Failed open file " + FileNameToString(filename_) + "for writing", errno);
}

void CHelperFile::Reopen(bool truncate) {
  if (filename_.empty()) {
    ThrowCLogeException("Failed reopen file - was not opened before");
  }
  this->Open(filename_, truncate);
}

void CHelperFile::Flush() {
  std::fflush(fd_);
}

void CHelperFile::Close() {
  if (nullptr != fd_) {
    std::fclose(fd_);
    fd_ = nullptr;
  }
}

void CHelperFile::Write(const RMemoryBuf& buf) {
  size_t msg_size = buf.size();
  auto data = buf.data();
  if (std::fwrite(data, 1, msg_size, fd_) != msg_size) {
    ThrowCLogeException("Failed writing to file " + FileNameToString(filename_), errno);
  }
}

size_t CHelperFile::Size() const {
  if (nullptr == fd_) {
    ThrowCLogeException("Cannot use size() on closed file " + FileNameToString(filename_));
  }
  return FileSize(fd_);
}

const RFileName& CHelperFile::FileName() const {
  return filename_;
}

std::tuple<RFileName, RFileName> CHelperFile::SplitByExtension(const RFileName& full_name) {
  auto exist = full_name.rfind('.');

  if (exist == RFileName::npos || 0 == exist || exist == full_name.size() - 1) {
    return std::make_tuple(full_name, RFileName());
  }

  auto folder_index = full_name.rfind(g_floder_sep);
  if (folder_index != RFileName::npos && folder_index >= exist - 1) {
    return std::make_tuple(full_name, RFileName());
  }

  return std::make_tuple(full_name.substr(0, exist), full_name.substr(exist));
}

} // !namespace log
} // !namespace afcore